package cn.wolfcode.wolf2w.service.impl;

import cn.wolfcode.wolf2w.domain.Destination;
import cn.wolfcode.wolf2w.domain.Region;
import cn.wolfcode.wolf2w.domain.StrategyCatalog;
import cn.wolfcode.wolf2w.query.DestinationQuery;
import cn.wolfcode.wolf2w.query.QueryObject;
import cn.wolfcode.wolf2w.repository.DestinationRepository;
import cn.wolfcode.wolf2w.service.IDestinationService;
import cn.wolfcode.wolf2w.service.IRegionService;
import cn.wolfcode.wolf2w.util.AssertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
//@Transactional
public class DestinationServiceImpl implements IDestinationService {

    //操作MongoDB数据库
    @Autowired
    private DestinationRepository destinationRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IRegionService regionService;


    @Override
    public void save(Destination destination) {
        destinationRepository.save(destination);
    }

    @Override
    public void delete(String id) {
        destinationRepository.deleteById(id);
    }

    @Override
    public void update(Destination destination) {
        destinationRepository.save(destination);
    }

    //查找区域下省份和城市
    @Override
    public List<Destination> search(String regionId) {
        AssertUtil.hasLength("id值不能为空",regionId);
        List<Destination> list = new ArrayList<>();
        //获取区域子级(省份)
        if ("-1".equals(regionId)) {
            //查询国内
            list=destinationRepository.findByParentName("中国");
        } else {
            //查询外国
            list = this.querySonDestinationByRegionId(regionId);
        }
        //获取省份子级(城市)
        for (Destination destination : list) {
            List<Destination> destinations = new ArrayList<>();
            //根据父亲id查询子级目的地(城市)
            destinations=destinationRepository.findByParentId(destination.getId());
            //只要五个城市
            if (destinations.size()>5) {
                destinations=destinations.subList(0,5);
            }
            //将查询出来的子级目的地设置到父亲属性中
            destination.setChildren(destinations);
        }
        return list;
    }

    public List<Destination> querySonDestinationByRegionId(String regionId) {
        Region region = regionService.findByOne(regionId);
        List<String> refIds = region.getRefIds();
        return destinationRepository.findByIdIn(refIds);
    }

    /**
     * 查询所有城市
     * @param deep
     * @return
     */
    @Override
    public Object findDestByDeep(int deep) {
        List<Destination> list = destinationRepository.findByDeep(deep);
        return list;
    }

    /**
     * 吐司
     * 查询当前对象所有父亲
     * @param parentId
     * @return
     */
    @Override
    public List<Destination> queryToasts(String parentId) {
        List<Destination> list = new ArrayList<>();
        createToasts(list,parentId);
        Collections.reverse(list);
        return list;
    }

    /**
     * 通过递归获取parentId对象所有父亲
     * @param list
     * @param parentId
     */
    public void createToasts(List list,String parentId) {
        //当parentId有值时执行下面逻辑
        if (!(StringUtils.hasLength(parentId))) {
            return;
        }
        //根据id获取Destination对象
        Destination destination = this.findByOne(parentId);
        //将获取到的Destination对象丢到集合中
        list.add(destination);
        //有父亲id进行递归操作
        if (StringUtils.hasLength(parentId)) {
            this.createToasts(list,destination.getParentId());
        }
    }

    /**
     * 修改目的地简介信息
     * @param id
     * @param info
     */
    @Override
    public void updateInfo(String id, String info) {
        //创建查询对象
        Query query = new Query();
        //查询条件
        query.addCriteria(Criteria.where("_id").is(id));
        //获取修改对象
        Update update = Update.update("info", info);
        mongoTemplate.updateMulti(query,update,Destination.class);
    }

    /**
     * 高查
     * @param qo
     * @return
     */
    @Override
    public Object query(DestinationQuery qo) {
        //创建查询对象
        Query query = new Query();
        //总条数
        long count = mongoTemplate.count(query, Destination.class);
        if (count==0) {
            //假设查询条数为0,返回空内容
            return Page.empty();
        }
        if (StringUtils.hasLength(qo.getKeyword())) {
            //设置模糊查询条件
            query.addCriteria(Criteria.where("name").regex(qo.getKeyword()));
        }
        //获取子级所有目的地(值不为空情况)
        if (StringUtils.hasLength(qo.getParentId())) {
            query.addCriteria(Criteria.where("parentId").is(qo.getParentId()));
        }
        count = mongoTemplate.count(query, Destination.class);
        //获取分页对象
        PageRequest pageRequest = PageRequest.of(qo.getCurrentPage()-1, qo.getPageSize(), Sort.Direction.ASC, "_id");

        query.with(pageRequest);
        //查询数据库(MongoDB)
        List<Destination> list = mongoTemplate.find(query, Destination.class);
        return new PageImpl<>(list,pageRequest,count);
    }

    @Override
    public Destination findByOne(String id) {
        return destinationRepository.findById(id).orElse(null);
    }

    /**
     * 查询匹配的城市(根据区域id查询Region对象,根据区域对象关联id查询城市)
     * @param rid
     * @return
     */
    @Override
    public List<Destination> getDestByRegionId(String rid) {
        //根据区域id查询Region对象
        Region region = regionService.findByOne(rid);
        //获取当前对象关联id
        List<String> refIds = region.getRefIds();
        return destinationRepository.findAllByIdIn(refIds);
    }

    @Override
    public List<Destination> findAll() {
        return destinationRepository.findAll();
    }
}
